package com.siwei.mes.sync.config;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.siwei.mes.entity.DownloadLaboratoryEntity;
import com.siwei.mes.entity.UploadLaboratoryEntity;
import com.siwei.mes.entity.dto.GenPrintInfoDto;
import com.siwei.mes.entity.dto.SyncLaboratoryDto;
import com.siwei.mes.entity.erp.RwdextraPrintEntity;
import com.siwei.mes.entity.sync.tc.SupplyTask;
import com.siwei.mes.entity.sync.tc.Waybill;
import com.siwei.mes.service.erp.RwdextraExtendService;
import com.siwei.mes.service.erp.RwdextraService;
import com.siwei.mes.service.laboratory.UploadAndDownloadAssociationService;
import com.siwei.mes.sync.erp.entity.ItemorderFinish;
import com.siwei.mes.sync.erp.entity.NewTrwd;
import com.siwei.mes.sync.erp.entity.SyncSupplierCompanyMaterials;
import com.siwei.mes.sync.erp.entity.UpdateMix;
import com.siwei.mes.sync.erp.service.SyncErpErpTrwdService;
import com.siwei.mes.sync.erp.service.SyncErpSupplierCompanyMaterialsService;
import com.siwei.mes.sync.tc.service.SyncTcSupplyTaskService;
import com.siwei.mes.sync.tc.service.SyncTcWaybillService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

/**
 * @Description: 同步队列处理数据
 * @Version: 1.0
 * @author: yangke
 * @date: 2023/12/30 21:09
 */
@Slf4j
@Service
public class SyncProcessorService {
    @Resource
    private SyncProcessorInitializing syncProcessorInitializing;
    @Resource
    private SyncTcSupplyTaskService tcSupplyTask;
    @Resource
    private SyncTcWaybillService tcWaybill;
    @Resource
    private SyncErpSupplierCompanyMaterialsService syncErpSupplierCompanyMaterialsService;
    @Resource
    private SyncErpErpTrwdService syncErpErpTrwdService;
    @Resource
    private UploadAndDownloadAssociationService uploadAndDownloadAssociationService;
    @Resource
    private RwdextraExtendService rwdextraExtendService;
    @Resource
    private RwdextraService rwdextraService;


    /**
     * 类型 -> 处理函数 注册表
     */
    private static final Map<Class<?>, Consumer<Object>> HANDLERS = new ConcurrentHashMap<>();

    /**
     * 容器启动完成后立即执行，将所有待同步的数据类型与对应的业务处理逻辑注册到 HANDLERS 映射表。
     * 后续 processRequest 仅通过对象类型即可快速定位并执行相应的同步逻辑。
     */
    @PostConstruct
    public void init() {
        // 统一注册：类型 -> 对应的 service 方法
        reg(SupplyTask.class, o -> tcSupplyTask.operateTcSupplyTask(cast(o, SupplyTask.class)));
        reg(Waybill.class, o -> tcWaybill.operateTcWaybill(cast(o, Waybill.class)));
        reg(SyncSupplierCompanyMaterials.class, o -> syncErpSupplierCompanyMaterialsService.saveOrUpdate(cast(o, SyncSupplierCompanyMaterials.class)));
        reg(NewTrwd.class, o -> syncErpErpTrwdService.newTrwd(cast(o, NewTrwd.class)));
        reg(UpdateMix.class, o -> syncErpErpTrwdService.updateMix(cast(o, UpdateMix.class)));
        reg(ItemorderFinish.class, o -> syncErpErpTrwdService.itemorderFinish(cast(o, ItemorderFinish.class)));
        reg(UploadLaboratoryEntity.class, o -> uploadAndDownloadAssociationService.uploadLaboratory(cast(o, UploadLaboratoryEntity.class)));
        reg(DownloadLaboratoryEntity.class, o -> uploadAndDownloadAssociationService.downloadLaboratory(cast(o, DownloadLaboratoryEntity.class)));
        reg(RwdextraPrintEntity.class, o -> rwdextraExtendService.setRwdextraPrintInfo(cast(o, RwdextraPrintEntity.class)));
        reg(GenPrintInfoDto.class, o -> rwdextraService.genPrintInfo(cast(o, GenPrintInfoDto.class).getFrwdList()));
        reg(SyncLaboratoryDto.class, o -> syncErpErpTrwdService.syncLaboratoryInfoDto(cast(o, SyncLaboratoryDto.class)));
    }


    /**
     * 处理请求
     *
     * @param entityObject
     */
    public void processRequest(Object entityObject) {
        Consumer<Object> handler = HANDLERS.get(entityObject.getClass());
        if (handler == null) {
            log.warn("找不到对应类型, 入参：{}", JSON.toJSONString(entityObject));
            return;
        }
        try {
            handler.accept(entityObject);
        } catch (Exception e) {
            log.error("执行报错, 类型：{}，入参：{}", entityObject.getClass(), JSON.toJSONString(entityObject), e);
        }
    }

    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 将任意对象安全地转换为指定类型。
     * 若对象已是目标类型，直接强转；否则使用 ObjectMapper 进行转换。
     *
     * @param obj   待转换的对象
     * @param clazz 目标类型
     * @param <T>   目标类型泛型
     * @return 转换后的目标类型实例
     */
    @SuppressWarnings("unchecked")
    private static <T> T cast(Object obj, Class<T> clazz) {
        return clazz.isInstance(obj) ? (T) obj : MAPPER.convertValue(obj, clazz);
    }


    /**
     * 将指定类型及其对应的处理逻辑注册到 HANDLERS 映射表中。
     *
     * @param clazz    待同步数据的类型
     * @param consumer 对该类型数据的具体处理逻辑
     */
    private void reg(Class<?> clazz, Consumer<Object> consumer) {
        HANDLERS.put(clazz, consumer);
    }


    /**
     * 添加到队列
     *
     * @param entity
     */
    public void submitRequest(Object entity) {
        boolean added = syncProcessorInitializing.submitRequest(entity);
        if (!added) {
            log.error("无法将对象添加到队列，队列可能已满，对象信息: {}", JSON.toJSONString(entity));
        }
    }
}
